#pragma once
#include "DXAMLCommon.h"

class CUIElement;
class VisualTree;
class CDOCollection;
class CDependencyObject;
class CPopup;




class CFocusManager :
	public IObject
{

public: 
	static HRESULT Create(CFocusManager * * ppObject, struct ICoreServices * pCoreService, VisualTree * pVisualTree);
	struct IDependencyObject * GetFocusedElement();
private: 
	struct IDependencyObject * GetFirstFocusableElement(struct IDependencyObject * pSearchStart, struct IDependencyObject * pFirstFocus);
public: 
	CUIElement * GetFirstFocusableElement();
	struct IDependencyObject * GetFirstFocusableElement(struct IDependencyObject * pStartElement);
private: 
	struct IDependencyObject * GetLastFocusableElement(struct IDependencyObject * pSearchStart, struct IDependencyObject * pLastFocus);
public: 
	struct IDependencyObject * GetLastFocusableElement(struct IDependencyObject * pStartElement);
	void SetPluginFocusStatus(bool bPluginFocused);
	XBOOL IsPluginFocused();
	XBOOL SetFocusedElement(struct IDependencyObject * pFocusedElement, enum FocusState focusState);
	HRESULT SetFocusOnNextFocusableElement(enum FocusState focusState);
	void ClearFocus();
	struct IDependencyObject * GetFirstFocusableElementFromRoot(bool bReverse);
	XBOOL CanProcessTabStop(XBOOL bReverse);
	XBOOL CanTabOutOfPlugin();
	void SetCanTabOutOfPlugin(XBOOL bCanTabOutOfPlugin);
	XBOOL ProcessTabStop(XBOOL bPressedShift);
	CUIElement * GetNextFocusableElement();
	HRESULT NotifyFocusChanged(XBOOL bringIntoView);
	virtual XUINT32 AddRef();
	virtual XUINT32 Release();
	XBOOL IsFocusable(struct IDependencyObject * pObject);
	HRESULT SetVisualTree(VisualTree * pVisualTree);
	XBOOL CanHaveFocusableChildren(struct IDependencyObject * pParent);

private: 
	CFocusManager(struct ICoreServices * pCoreService, VisualTree * pVisualTree);
	~CFocusManager();
	struct IDependencyObject * GetNextTabStop();
	struct IDependencyObject * GetNextTabStopInternal(struct IDependencyObject * pParent, struct IDependencyObject * pCurrent, struct IDependencyObject * pCandidate, XBOOL * bCurrentPassed, struct IDependencyObject * * pCurrentCompare);
	struct IDependencyObject * GetPreviousTabStop();
	struct IDependencyObject * GetPreviousTabStopInternal(struct IDependencyObject * pParent, struct IDependencyObject * pCurrent, struct IDependencyObject * pCandidate, XBOOL * bCurrentPassed, struct IDependencyObject * * pCurrentCompare);
	XINT32 CompareTabIndex(struct IDependencyObject * pControl1, struct IDependencyObject * pControl2);
	XBOOL IsFocusOnFirstTabStop();
	XBOOL IsFocusOnLastTabStop();
	CUIElement * GetParentElement(struct IDependencyObject * pCurrent);
	struct IDependencyObject * GetFirstFocusableElementInternal(struct IDependencyObject * pSearchStart, struct IDependencyObject * pFirstFocus);
	struct IDependencyObject * GetLastFocusableElementInternal(struct IDependencyObject * pSearchStart, struct IDependencyObject * pLastFocus);
	XBOOL IsVisible(struct IDependencyObject * pObject);
	XBOOL CanHaveChildren(struct IDependencyObject * pObject);
	CDOCollection * GetFocusChildren(struct IDependencyObject * pObject);
	struct IDependencyObject * GetFocusParent(struct IDependencyObject * pObject);
	XINT32 GetTabIndex(struct IDependencyObject * pObject);
	CDependencyObject * GetRootOfPopupSubTree(struct IDependencyObject * pObject);
	enum KeyboardNavigationMode GetTabNavigation(struct IDependencyObject * pObject);
	XBOOL CanBeTabStop(struct IDependencyObject * pObject);
	HRESULT UpdateFocus(struct IDependencyObject * pNewFocus, enum FocusState focusState, XBOOL * pfSuccess);
	HRESULT RaiseLostFocusEvent(struct IDependencyObject * pLostFocusElement);
	HRESULT RaiseGotFocusEvent(struct IDependencyObject * pGotFocusElement);
	XBOOL CanRaiseFocusEventChange();
	struct IDependencyObject * GetNextTabStopFromLightDismissPopup(CPopup * pPopup, XBOOL bReverse);
	XUINT32 m_cRef;
	struct IDependencyObject * m_pFocusedElement;
	CCoreServices * m_pCoreService;
	VisualTree * m_pVisualTree;
	XBOOL m_bPluginFocused;
	XBOOL m_bCanTabOutOfPlugin;
	XBOOL m_isPrevFocusTextControl;


};